為了在python GUI 程式開發時有更好的開發者體驗, 筆者喜歡先收集別人的痛點及各種解決方案, 整理成屬於自己的優化方案再導入到GUI專案中, 而Exception 的呈現方式就是其中一個痛點.
引用自近期網友詢問Python 的Try Exception的問題片段 ...
引用來源: https://reurl.cc/XlWje3
在專案中有很多使用者會使用exception 去做例外的攔截, 但很常遇到的狀況是Exception並不會把完整的CallStack及位置顯示出來, 這就增添除錯時的困難度, 尤其在大型專案或多檔案的程式碼中, 不處理好就會演變成一場大災難.
來看個簡單的例子:
dict_a = {0:'hello',1:'hi'}
def run():
try:
print ("Hello, this is dmeo.\n")
print(dict_a[2])
print ("End")
except Exception as err:
print(err)
run()
例外發生的時候看不到完整的callstack 及行號
這次筆者使用traceback , 這個內建的模組做實驗
import sys
import traceback
dict_a = {0:'hello', 1:'hi'}
def run():
try:
print ("Hello, this is demo.\n")
print (dict_a[2])
print ("End")
except Exception as err:
err_type = err.__class__.__name__ # 取得錯誤的class 名稱
info = err.args[0] # 取得詳細內容
detains = traceback.format_exc() # 取得完整的tracestack
n1, n2, n3 = sys.exc_info() #取得Call Stack
lastCallStack = traceback.extract_tb(n3)[-1] # 取得Call Stack 最近一筆的內容
fn = lastCallStack [0] # 取得發生事件的檔名
lineNum = lastCallStack[1] # 取得發生事件的行數
funcName = lastCallStack[2] # 取得發生事件的函數名稱
errMesg = f"FileName: {fn}, lineNum: {lineNum}, Fun: {funcName}, reason: {info}, trace:\n {traceback.format_exc()}"
print(errMesg)
run()
流程
執行結果
結論
我們可以把這個好用的模組使用方式包成一個簡單的模組, 搭配logging或寫成檔案去做相關的紀錄, 這樣就可以減少程式出錯後的除錯難度
參考資料